<?xml version="1.0" encoding="utf-8"?> 
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
 <title type="text">Gnaily's Blog: Posts tagged 'SQL'</title>
 <link rel="self" href="http://yangliang.site/feeds\SQL.atom.xml" />
 <link href="http://yangliang.site/tags\SQL.html" />
 <id>urn:http-yangliang-site:-tags-SQL-html</id>
 <updated>2018-04-05T16:00:00Z</updated>
 <entry>
  <title type="text">简明SQL</title>
  <link rel="alternate" href="http://yangliang.site/2018\04\%E7%AE%80%E6%98%8Esql.html?utm_source=SQL&amp;utm_medium=Atom" />
  <id>urn:http-yangliang-site:-2018-04-E7-AE-80-E6-98-8Esql-html</id>
  <published>2018-04-05T16:00:00Z</published>
  <updated>2018-04-05T16:00:00Z</updated>
  <author>
   <name>Gnaily</name></author>
  <content type="html">
&lt;p&gt;[TOC]&lt;/p&gt;

&lt;h3 id="表结构操作"&gt;表结构操作&lt;/h3&gt;

&lt;p&gt;查看表结构&lt;/p&gt;

&lt;div class="brush: sql"&gt;
 &lt;pre&gt;&lt;code&gt;desc  tablename ; -- 查看表tablename的结构信息&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;创建表结构&lt;/p&gt;

&lt;div class="brush: sql"&gt;
 &lt;pre&gt;&lt;code&gt;CREATE TABLE tablename(
  -- db_data_type是数据库的数据类型，比如int(5)，varchar(64)
  column_name_1   db_data_type
  column_name_2   db_data_type
  ...
  column_name_n   db_data_type 
) ;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;增加表的字段&lt;/p&gt;

&lt;div class="brush: sql"&gt;
 &lt;pre&gt;&lt;code&gt;alter tablename
-- db_data_type是数据库的数据类型，比如int()，varchar(64)
add   column_name_1   db_data_type
add   column_name_2   db_data_type
...
add   column_name_n   db_data_type ; &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;删除表的字段&lt;/p&gt;

&lt;div class="brush: sql"&gt;
 &lt;pre&gt;&lt;code&gt;alter tablename
drop  column column_name_1  
drop  column column_name_2
...
drop  column column_name_n ;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;删除表&lt;/p&gt;

&lt;div class="brush: sql"&gt;
 &lt;pre&gt;&lt;code&gt;drop tablename ;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;创建索引：&lt;/p&gt;

&lt;div class="brush: sql"&gt;
 &lt;pre&gt;&lt;code&gt;-- 在table_name表的column_name列上创建一个简单的索引。允许使用重复的索引值。
create index index_name
on tablename (column_name) ;
 
-- 在table_name表的column_name列上创建一个唯一的索引。唯一的索引意味着任意两个行不能拥有相同的索引值。
create uinqe index index_name
on tablename (column_name) ;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id="检索数据select"&gt;检索数据select&lt;/h3&gt;

&lt;p&gt;数据检索SQL一般由select子句，from子句，join子句、where子句、group by子句、having子句 、order by子句组成。from子句后的其他子句不是必须要有的，根据实际需要进行使用。各个子句出现的相对顺序不能颠倒。Select检索数据的&lt;code&gt;逻辑&lt;/code&gt;处理流程为：&lt;/p&gt;

&lt;p&gt;join连接表&amp;mdash;&amp;gt;where 对行过滤&amp;mdash;&amp;gt;group by分组&amp;mdash;&amp;gt;having对组过滤&amp;mdash;&amp;gt;聚集函数处理&amp;mdash;&amp;gt;order by排序&amp;mdash;&amp;gt;输出结果。&lt;/p&gt;

&lt;p&gt;当有子查询时先处理内层子查询，再处理外层查询。&lt;/p&gt;

&lt;div class="brush: sql"&gt;
 &lt;pre&gt;&lt;code&gt;select
   列名 -- 多个列名用逗号隔开，非聚集列（没有被聚集函数作用的列）必须是分组列名的子集
from
   表名
left|right|inner  join   表名   on   关联条件
where  
   过滤行条件
group by  
   分组列名  -- 多个列名用逗号隔开
having
   过滤分组条件  -- 过滤分组条件中的非聚集列（没有被聚集函数作用的列）必须是分组列名的子集
order by
   排序字段&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;简单检索SQL&lt;/p&gt;

&lt;div class="brush: sql"&gt;
 &lt;pre&gt;&lt;code&gt;-- 检索tablename表的所有列的结果
select *  from tablename;
-- 检索tablename表的指定列的结果
select column_name_1,column_name_2,... column_name_n from tablename; &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;过滤行使用where&lt;/p&gt;

&lt;p&gt;where关系运算符：&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;大于( &amp;gt;）:只检索出满足指定字段大于指定值的数据，其余被过滤掉。&lt;/li&gt;
 &lt;li&gt;小于（&amp;lt;）：只检索出满足指定字段小于指定值的数据，其余被过滤掉&lt;/li&gt;
 &lt;li&gt;等于（=）：只检索出满足指定字段等于指定值的数据，其余被过滤掉&lt;/li&gt;
 &lt;li&gt;大于或等于（&amp;gt;=）:只检索出满足指定字段大于或等于指定值的数据，其余被过滤掉&lt;/li&gt;
 &lt;li&gt;小于或等于（&amp;lt;=）:只检索出满足指定字段小于或等于指定值的数据，其余被过滤掉&lt;/li&gt;
 &lt;li&gt;不等于（&amp;lt;&amp;gt;或！=）：只检索出满足指定字段不等于指定值的数据，其余被过滤掉&lt;/li&gt;
 &lt;li&gt;in操作符：只检索出满足指定字段在指定数据集合里的数据，其余被过滤掉&lt;/li&gt;
 &lt;li&gt;like通配匹配符：只检索出满足指定字段能与like后跟的搜索模式匹配的数据，其余被过滤掉&lt;/li&gt;
 &lt;li&gt;百分号通配符（%）：匹配任意字符出现任意次数。可以用在搜索模式的开始、中间和结尾处。&lt;/li&gt;
 &lt;li&gt;下划线通配符（_）:只匹配单个字符&lt;/li&gt;
 &lt;li&gt;方括号通配符（[ ]）：方括号通配符里用于指定一个字符集， 只匹配出一个在该字符集里的字符。&lt;/li&gt;
 &lt;li&gt;and操作符：组合多个条件，检索出同时满足多个条件的数据&lt;/li&gt;
 &lt;li&gt;or操作符：组合多个条件，检索出满足条件之一的数据&lt;/li&gt;&lt;/ul&gt;

&lt;div class="brush: sql"&gt;
 &lt;pre&gt;&lt;code&gt;-- useage:
where
    column_name_1=value1
and column_name_2&amp;gt;value2
and column_name_3 in ('张三'，'李四')
    -- 匹配end结尾的字符串
and column_name_4 like '%end' &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;检索结果分组用group by&lt;/p&gt;

&lt;p&gt;group by关键字指示DBMS对指定列中数据都相同的分为一组，group by 后的列相当分组的维度。&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;group by 可以包含任意数目的列&lt;/li&gt;
 &lt;li&gt;group by 子句中列出的每个列都必须是检索列或有效表达式（不能是聚集函数）。如果select 中使用列表达式，group by 中也要是表达式而不能是表达式的别名。&lt;/li&gt;
 &lt;li&gt;除进行聚集计算的列外，select中的每个列必须是group by中给出的列。&lt;/li&gt;
 &lt;li&gt;分组列中如果有null值，则列的所有null值将分为一个组&lt;/li&gt;&lt;/ul&gt;

&lt;div class="brush: sql"&gt;
 &lt;pre&gt;&lt;code&gt;-- useage:
select
    -- select输出的列必须是group by中的列
    column_name_1,column_name_2 
from
    tablename
group by
    -- 检索数据中这几个分组列的各个列的值相同的分为一组
    column_name_1,column_name_2,column_name_3 ;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;过滤检索结果中的分组用having&lt;/p&gt;

&lt;p&gt;where对行进行过滤，having则对组进行过滤。having支持所有where子句中的操作符号。由于where在对数据分组前进数据行过滤，having则在分组后进行组的过滤，所以where排除的行不会包含在分组中，having过滤条件的字段必须是group by 中的字段。where中不能包含聚集函数，而having中可以包含聚集函数。&lt;/p&gt;

&lt;div class="brush: sql"&gt;
 &lt;pre&gt;&lt;code&gt;-- useage:
select
    -- select输出的列必须是group by中的列
    column_name_1,column_name_2 
from
    tablename
group by
    -- 检索数据中这几个分组列的各个列的值相同的分为一组
    column_name_1,column_name_2,column_name_3
having
      column_name_1=value1
  and column_name_2&amp;gt;value2 ; &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;排序检索结果用order by&lt;/p&gt;

&lt;div class="brush: sql"&gt;
 &lt;pre&gt;&lt;code&gt;select
    column_name_1,column_name_2,column_name_3,column_name_4 
from
    tablename
order by
    column_name_2 desc,column_name_3 asc ;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;汇总检索结果使用聚集函数&lt;/p&gt;

&lt;p&gt;聚集函数：运行在列的分组上，返回单个值的函数。如果有进行分组，聚集函数在分组后进行聚集&lt;/p&gt;

&lt;p&gt;常用聚集函数：&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;AVG（column）：返回指定列的均值&lt;/li&gt;
 &lt;li&gt;COUNT（column）：返回指定列的值的数目&lt;/li&gt;
 &lt;li&gt;MAX（column）：返回指定列的最大值&lt;/li&gt;
 &lt;li&gt;MIN（column）：返回指定列的最大值&lt;/li&gt;
 &lt;li&gt;SUM（column）：返回指定列值之和&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;聚集函数参数：聚集函数作用的的列名前可以加上distinct或all参数。all为默认参数，聚集函数作用的的列名前不加参数时默认为all，会对指定列的所用行进行计算，如果聚集函数作用的的列名前加上distinct参数，只会对指定列的不同值进行计算。有些数据库并不支持distinct。&lt;/p&gt;

&lt;div class="brush: sql"&gt;
 &lt;pre&gt;&lt;code&gt;-- useage:
select
    -- select输出的非聚集列必须是group by中的列
    AVG(column_name_1) ,
    COUNT(column_name_2) ,
    MAX(column_name_3)
    SUM(column_name_5),
    column_name_6,
    column_name_7
from
    tablename
where
    	column_name_1=value1
	and column_name_2&amp;gt;value2
group by
    -- 检索数据中这几个分组列的各个列的值相同的分为一组
    column_name_6,
    column_name_7
    column_name_8
having
      MIN(column_name_4)=value ;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;关联查询用join&amp;hellip;on&amp;hellip;&lt;/p&gt;

&lt;p&gt;关联查询中的笛卡尔积&lt;/p&gt;

&lt;p&gt;左连接left join right-table on&amp;hellip;:包含左表的所有记录甚至是右表中没有和它匹配的记录。&lt;/p&gt;

&lt;p&gt;右连接right join right-table on&amp;hellip;:包含右表的所有记录甚至是左表中没有和它匹配的记录。&lt;/p&gt;

&lt;p&gt;内连接inner join&amp;hellip;.on&amp;hellip; :又称之为等值连接。仅仅选出两张表中互相匹配的记录&lt;/p&gt;

&lt;p&gt;关联查询耗资源，不要连接不必要的表。&lt;/p&gt;

&lt;p&gt;关联查询与子查询可转换。&lt;/p&gt;

&lt;p&gt;自连接：&lt;/p&gt;

&lt;p&gt;全外部连接&lt;/p&gt;

&lt;div class="brush: sql"&gt;
 &lt;pre&gt;&lt;code&gt;-- useage
 &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;组合查询使用union&lt;/p&gt;

&lt;p&gt;union 操作符用于合并两个或多个 select 语句的结果集，要求select 子句的列的数据类型相似。&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;
  &lt;p&gt;多个查询中从不同表返回类似结构数据&lt;/p&gt;&lt;/li&gt;
 &lt;li&gt;
  &lt;p&gt;对单个表执行多个查询，按单个表返回查询数据&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;union的结果不包含重复值，union all的结果包含重复值。&lt;/p&gt;

&lt;div class="brush: sql"&gt;
 &lt;pre&gt;&lt;code&gt;-- useage
 &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;子查询：嵌套在其他查询中的完整查询语句，可以嵌套的地方有&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;把子查询用作返回列&lt;/li&gt;
 &lt;li&gt;把子查询用作where条件&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;子查询总是从内向外处理。做为子查询的select语句只能查询单个列。&lt;/p&gt;

&lt;h3 id="插入数据insert"&gt;插入数据insert&lt;/h3&gt;

&lt;p&gt;插入一行数据&lt;/p&gt;

&lt;div class="brush: sql"&gt;
 &lt;pre&gt;&lt;code&gt;insert into tablename (column_name_1,column_name_2, ... column_name_n) values(value1,value2, ... valuen );&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;插入从表中检索出来的数据（可以是多行）insert into..select&amp;hellip;&lt;/p&gt;

&lt;div class="brush: sql"&gt;
 &lt;pre&gt;&lt;code&gt;insert into  tablename (column_name_1,column_name_2, ... column_name_n)
-- 这里是一条检索数据的sql
select column_name_1,column_name_2, ... column_name_n from ....  ;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;复制数据到一个表中 select &amp;hellip;into&amp;hellip;&lt;/p&gt;

&lt;div class="brush: sql"&gt;
 &lt;pre&gt;&lt;code&gt;-- useage:
select column_name_1,column_name_2, ... column_name_n into tablename
from tablename
[left join ...  on ... ]
[where ... ]
[group by ... ]
[having ... ]
[order by ... ]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id="更新数据update"&gt;更新数据update&lt;/h3&gt;

&lt;p&gt;使用where条件限定需要更新的行，省略where将更新整个表。编写时需要注意where条件的正确性，避免误操作。&lt;/p&gt;

&lt;div class="brush: sql"&gt;
 &lt;pre&gt;&lt;code&gt;-- 更新满足where限定条件的行，省略where将更新表的所有行
update
  tablename 
set
  column_name_1=value1 ,
  column_name_2=value2,
  ...
  column_name_n=valuen
where ...;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id="删除数据delete"&gt;删除数据delete&lt;/h3&gt;

&lt;p&gt;使用where条件限定需要删除的行，省略where将删除整个表的数据。编写时需要注意where条件的正确性，避免误操作。&lt;/p&gt;

&lt;div class="brush: sql"&gt;
 &lt;pre&gt;&lt;code&gt;-- 从tablename表删除满足where条件的行，省略where时将删除改表的所有数据
delete from tablename  where ... ;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id="sql优化思路"&gt;SQL优化思路&lt;/h3&gt;

&lt;ul&gt;
 &lt;li&gt;优化select子句&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt; 用需要查询列的名字代替通配符*。使用SELECT &lt;em&gt;时一方面数据库需要去查询表的元数据来将&lt;/em&gt; 解析为表的具体字段， 另一方面会查询出表所有列的数据，而有的列的数据我们并不需要。这两者都会造成执行效率的下降。&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;
  &lt;p&gt;优化join子句&lt;/p&gt;&lt;/li&gt;
 &lt;li&gt;
  &lt;p&gt;优化where子句&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt; 优化or条件：对于含有or的查询子句，如果要利用索引，则or之间的每个条件都必须要用到索引；如果没有索引则需要考虑增加索引。&lt;/p&gt;

&lt;p&gt; 优化or为union查询。&lt;/p&gt;

&lt;ul&gt;
 &lt;li&gt;
  &lt;p&gt;优化子查询为关联查询：join之所以比子查询更有效率是因为其不需要建立临时表来完成这个需要多个查询步骤的工作。&lt;/p&gt;&lt;/li&gt;
 &lt;li&gt;
  &lt;p&gt;使用SQL hint ：在SQL中人为加入提示来达到优化操作的目的。&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;</content></entry></feed>